package com.pactera.asmp.server.restfullapi;

import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.pactera.asmp.server.common.constants.Constants;
import com.pactera.asmp.server.common.constants.PermissionCode;
import com.pactera.asmp.server.common.constants.ResultCode;
import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import com.pactera.asmp.server.entity.DeviceInfoSearchDTO;
import com.pactera.asmp.server.entity.ResponseResult;
import com.pactera.asmp.server.pojo.DeviceInfo;
import com.pactera.asmp.server.service.IDeviceServcie;
import com.pactera.asmp.server.utils.PageDataResult;

import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

/**
 * @ProjectName: tlsserver
 * @Package com.pactera.asmp.server.restfullapi
 * @ClassName: RestfullDeviceApi
 * @Description: 设备接入
 * @Date 2020/06/01 11:05
 * @Author lvzhiqiang
 * @Version 1.0
 */
@RestController
@RequestMapping("/api/v1")
public class RestfullDeviceApi {

    private static final Logger logger = LoggerFactory
            .getLogger(RestfullDeviceApi.class);

    @Autowired
    private IDeviceServcie mDeviceServiceImpl;

    @RequiresPermissions(value = {PermissionCode.DEVICE_LIST, PermissionCode.TEST_CASE, PermissionCode.TEST_TASK}, logical= Logical.OR)
    @GetMapping(value = "/device", produces = "application/json;charset=UTF-8")
    public ResponseResult getDeviceList(@RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "limit", required = false) Integer limit,
            @RequestParam(value = "masterUid", required = false) Integer masterUid,
            @RequestParam(value = "masterComputerId", required = false) Integer masterComputerId,
            @RequestParam(value = "type", required = false) Integer type,
            @RequestParam(value = "status", required = false) Integer status) {
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        PageDataResult pdr;
        if (null == page || 0 == page) {
            page = 1;
        }
        if (null == limit || 0 == limit) {
            limit = 10;
        }

        if(page < 0 || limit < 0) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("totals", 0);
            jsonObject.put("list", Lists.newArrayList());
            responseResult.setData(jsonObject);
            return responseResult;
        }
        DeviceInfoSearchDTO deviceInfoSearchDTO = new DeviceInfoSearchDTO();
        deviceInfoSearchDTO.setPage(page);
        deviceInfoSearchDTO.setLimit(limit);
        deviceInfoSearchDTO.setMasterUid(masterUid);
        deviceInfoSearchDTO.setMasterComputerId(masterComputerId);
        deviceInfoSearchDTO.setType(type);
        deviceInfoSearchDTO.setStatus(status);
        pdr = mDeviceServiceImpl.get(deviceInfoSearchDTO, page, limit);
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("totals", pdr.getTotals());
        jsonObject.put("list", pdr.getList());
        responseResult.setData(jsonObject);
        return responseResult;
    }

    @RequiresPermissions({PermissionCode.DEVICE_LIST})
    @PutMapping(value = "/device", produces = "application/json;charset=UTF-8")
    public ResponseResult updateDevice(@RequestBody DeviceInfo deviceInfo) {
        logger.info("/api/v1/devcie updateDevice deviceInfo :{}" , deviceInfo);
        if (deviceInfo == null || deviceInfo.getId() == 0 || StringUtils.isEmpty(deviceInfo.getDuid()) || StringUtils.isEmpty(deviceInfo.getSn())) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        if (StringUtils.isNotEmpty(deviceInfo.getNickName())) {
            if(!deviceInfo.getNickName().matches(Constants.REGEXP_FIRST_LAST_NOT_SPACE)) {
                return new ResponseResult(ResultCode.PARAM_TYPE_BIND_ERROR);
            }
        }
        return mDeviceServiceImpl.update(deviceInfo) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.SYSTEM_INNER_ERROR);
    }

    @RequiresPermissions({PermissionCode.DEVICE_LIST})
    @DeleteMapping(value = "/device", produces = "application/json;charset=UTF-8")
    public ResponseResult deleteDevice(@RequestBody List<Integer> datas) {
        logger.info("/api/v1/devcie deleteDevice devcieDTO :{}" , datas);
        if (datas.isEmpty()) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        return mDeviceServiceImpl.delete(datas) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.SYSTEM_INNER_ERROR);
    }

    @RequiresPermissions({PermissionCode.DEVICE_LIST})
    @PatchMapping(value = "/device",produces = "application/json;charset=UTF-8")
    public ResponseResult operationDevice(@RequestBody JSONObject params) {
        String duid = params.getString("duid");
        Integer userId = params.getInteger("userId");
        Integer status = params.getInteger("status");
        String userName = params.getString("userName");
        logger.info("/api/v1/devcie operationDevice duid :{}, userId:{}, status:{}",duid,userId,status);
        ResponseResult responseResult;
        if(StringUtils.isEmpty(duid) || userId == null || status == null){
            responseResult = new ResponseResult(ResultCode.PARAM_IS_BLANK);
            return responseResult;
        }
        return mDeviceServiceImpl.operationDevice(duid,userId, status, userName) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.BUSINESS_DEVICE_OPER_ERR);
    }

    @RequiresPermissions({PermissionCode.DEVICE_LIST})
    @PatchMapping(value = "/auxdevice",produces = "application/json;charset=UTF-8")
    public ResponseResult operationAuxDevice(@RequestBody JSONObject params) {
        String duid = params.getString("duid");
        Integer userId = params.getInteger("userId");
        Integer status = params.getInteger("status");
        String userName = params.getString("userName");
        logger.info("/api/v1/auxdevice operationDevice duid :{}, userId:{}, status:{}",duid,userId,status);
        ResponseResult responseResult;
        if(StringUtils.isEmpty(duid) || userId == null || status == null){
            responseResult = new ResponseResult(ResultCode.PARAM_IS_BLANK);
            return responseResult;
        }
        return mDeviceServiceImpl.operationDeviceForAux(duid,userId, status, userName) ? new ResponseResult(ResultCode.SUCCESS) : new ResponseResult(ResultCode.BUSINESS_DEVICE_OPER_ERR);
    }

    /**
     * @api {GET} /api/v1/device/listByProjectId 获取设备列表
     * @apiVersion 1.0.0
     * @apiGroup 设备接口
     * @apiName deviceListByProjectId
     * @apiDescription 根据项目获取设备列表
     * @apiParam (请求参数) {Number} projectId 项目ID，-1时查询未绑定项目的设备列表，0时查询全部设备列表，大于0按实际查询
     * @apiParam (请求参数) {Number} masterComputerId 根据上位机查询设备列表，可选
     * @apiParamExample 请求参数示例
     * projectId=0&masterComputerId=9088
     * @apiHeader {String} Authorization Bearer xxx
     * @apiHeaderExample {json} 请求头样例:
     * { "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiNTAiLCJjaGFubmVsSWQiOjUsInJvbGVJZCI6IjIiLCJjcmVhdGVUaW1lIjoxNjE1MzU5MDgxNDY1LCJsb2NhbGhvc3QiOiJCQUIxOTAwMjE1Iiwic3ViIjoiYWRtaW4iLCJpc3MiOiIyZDBhNDI2MTY5MjYwYzA4NmIxNWU4MzlhYmEyMGUwOSIsImlhdCI6MTYxNTM1OTA4MSwiYXVkIjoicmVzdGFwaXVzZXIiLCJleHAiOjE2MTc5NTEwODEsIm5iZiI6MTYxNTM1OTA4MX0.BpUVtIE4kWyWKD8-b7lAv1611rv5N1U1q0VO4ijD0P0" }
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccessExample 响应结果示例
     * {"code":3246,"data":{},"message":"w8xz"}
     */
    @RequiresPermissions(value = {PermissionCode.DEVICE_LIST, PermissionCode.CAN_SIGNAL,
            PermissionCode.REMOTE_DEBUGGING, PermissionCode.PROJECT_LIST,
            PermissionCode.TEST_CASE, PermissionCode.TEST_TASK}, logical= Logical.OR)
    @GetMapping("/device/listByProjectId")
    public ResponseResult deviceListByProjectId(Integer projectId, Integer masterComputerId) {
        logger.debug("/api/v1/device/listByProjectId projectId: {} ,masterComputerId:{}", projectId,masterComputerId);
        if (null == projectId) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        ResponseResult responseResult = new ResponseResult(ResultCode.SUCCESS);
        responseResult.setData(mDeviceServiceImpl.deviceListByProjectId(projectId, masterComputerId,null));
        return responseResult;
    }

    /**
     * @api {GET} /api/v1/device/deviceBindByProjectId 项目编辑时设备列表
     * @apiVersion 1.0.0
     * @apiGroup 设备接口
     * @apiName deviceBindByProjectId
     * @apiDescription 根据项目获取设备列表
     * @apiParam (请求参数) {Number} projectId 项目ID，-1时查询未绑定项目的设备列表，0时查询全部设备列表，大于0按实际查询
     * @apiParamExample 请求参数示例
     * projectId=10
     * @apiHeader {String} Authorization Bearer xxx
     * @apiHeaderExample {json} 请求头样例:
     * { "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiNTAiLCJjaGFubmVsSWQiOjUsInJvbGVJZCI6IjIiLCJjcmVhdGVUaW1lIjoxNjE1MzU5MDgxNDY1LCJsb2NhbGhvc3QiOiJCQUIxOTAwMjE1Iiwic3ViIjoiYWRtaW4iLCJpc3MiOiIyZDBhNDI2MTY5MjYwYzA4NmIxNWU4MzlhYmEyMGUwOSIsImlhdCI6MTYxNTM1OTA4MSwiYXVkIjoicmVzdGFwaXVzZXIiLCJleHAiOjE2MTc5NTEwODEsIm5iZiI6MTYxNTM1OTA4MX0.BpUVtIE4kWyWKD8-b7lAv1611rv5N1U1q0VO4ijD0P0" }
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccessExample 响应结果示例
     * {"code":3246,"data":{},"message":"w8xz"}
     */
    @RequiresPermissions(value = {PermissionCode.DEVICE_LIST, PermissionCode.CAN_SIGNAL,
            PermissionCode.REMOTE_DEBUGGING, PermissionCode.PROJECT_LIST,
            PermissionCode.TEST_CASE, PermissionCode.TEST_TASK}, logical= Logical.OR)
    @GetMapping("/device/deviceBindByProjectId")
    public ResponseResult deviceBindByProjectId(@RequestParam("projectId") Integer projectId) {
        logger.debug("/api/v1/device/deviceBindByProjectId projectId: {}", projectId);
        if (null == projectId) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        return ResponseResult.defaultSuccess(mDeviceServiceImpl.deviceBindByProjectId(projectId));
    }

    @GetMapping("/device/deviceUnBindByProjectId")
    public ResponseResult deviceUnBindByProjectId(@RequestParam("projectId") Integer projectId) {
        logger.debug("/api/v1/device/deviceUnBindByProjectId projectId: {}", projectId);
        if (null == projectId) {
            return new ResponseResult(ResultCode.PARAM_IS_BLANK);
        }
        return ResponseResult.defaultSuccess(mDeviceServiceImpl.deviceUnBindByProjectId(projectId));
    }

    @GetMapping("/device/deviceBindByMasterId")
    public ResponseResult deviceBindByMasterId(@RequestParam("masterId") Integer masterId) {
        logger.debug("/api/v1/device/deviceBindByMasterId masterId: {}", masterId);
        return ResponseResult.defaultSuccess(mDeviceServiceImpl.deviceBindByMasterId(masterId));
    }

    /**
     * @api {PUT} /api/v1/device/nickname updateDeviceNickName
     * @apiVersion 1.0.0
     * @apiGroup RestfullDeviceApi
     * @apiName updateDeviceNickName
     * @apiDescription 修改设备昵称
     * @apiParam (请求体) {Number} id ID
     * @apiParam (请求体) {String} nickName 昵称
     * @apiParamExample 请求体示例
     * {"nickName":"C6XbY","id":5981}
     * @apiHeader {String} Authorization Bearer xxx
     * @apiHeaderExample {json} 请求头样例:
     * { "Authorization": "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1dWlkIjoiNTAiLCJjaGFubmVsSWQiOjUsInJvbGVJZCI6IjIiLCJjcmVhdGVUaW1lIjoxNjE1MzU5MDgxNDY1LCJsb2NhbGhvc3QiOiJCQUIxOTAwMjE1Iiwic3ViIjoiYWRtaW4iLCJpc3MiOiIyZDBhNDI2MTY5MjYwYzA4NmIxNWU4MzlhYmEyMGUwOSIsImlhdCI6MTYxNTM1OTA4MSwiYXVkIjoicmVzdGFwaXVzZXIiLCJleHAiOjE2MTc5NTEwODEsIm5iZiI6MTYxNTM1OTA4MX0.BpUVtIE4kWyWKD8-b7lAv1611rv5N1U1q0VO4ijD0P0" }
     * @apiSuccess (响应结果) {Number} code
     * @apiSuccess (响应结果) {String} message
     * @apiSuccess (响应结果) {Object} data
     * @apiSuccessExample 响应结果示例
     * {"code":6387,"data":{},"message":"Pa7EKR1U"}
     */
    @RequiresPermissions({PermissionCode.DEVICE_LIST})
    @PostMapping(value = "/device/nickname", produces = "application/json;charset=UTF-8")
    public ResponseResult updateDeviceNickName(@RequestBody DeviceInfo deviceInfo) {
        logger.info("/api/v1/devcie/nickname deviceInfo :{}" , deviceInfo);
        return mDeviceServiceImpl.updateNickName(deviceInfo) >0 ? ResponseResult.defaultSuccess(null):ResponseResult.defaultFail(-1,"更新失败");
    }

    @PostMapping(value = "/device/devicePackageName", produces = "application/json;charset=UTF-8")
    public ResponseResult devicePackageName(@RequestBody DeviceInfo deviceInfo) {
        logger.info("/api/v1/devcie/devicePackageName deviceInfo :{}" , deviceInfo);
        return mDeviceServiceImpl.devicePackageName(deviceInfo);
    }
}
